// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//
#include <pollux/functions/lib/registration_helpers.h>
#include <pollux/functions/prestosql/date_time_functions.h>
#include <pollux/functions/sparksql/date_time_functions.h>

namespace kumo::pollux::functions::sparksql {
    void registerDatetimeFunctions(const std::string &prefix) {
        register_function<YearFunction, int32_t, Timestamp>({prefix + "year"});
        register_function<YearFunction, int32_t, Date>({prefix + "year"});
        register_function<WeekFunction, int32_t, Date>({prefix + "week_of_year"});
        register_function<YearOfWeekFunction, int32_t, Date>(
            {prefix + "year_of_week"});
        register_function<ToUtcTimestampFunction, Timestamp, Timestamp, Varchar>(
            {prefix + "to_utc_timestamp"});
        register_function<FromUtcTimestampFunction, Timestamp, Timestamp, Varchar>(
            {prefix + "from_utc_timestamp"});
        register_function<UnixDateFunction, int32_t, Date>({prefix + "unix_date"});
        register_function<UnixSecondsFunction, int64_t, Timestamp>(
            {prefix + "unix_seconds"});
        register_function<UnixTimestampFunction, int64_t>({prefix + "unix_timestamp"});
        register_function<UnixTimestampParseFunction, int64_t, Varchar>(
            {prefix + "unix_timestamp", prefix + "to_unix_timestamp"});
        register_function<
            UnixTimestampParseWithFormatFunction,
            int64_t,
            Varchar,
            Varchar>({prefix + "unix_timestamp", prefix + "to_unix_timestamp"});
        register_function<UnixTimestampParseWithFormatFunction, int64_t, Timestamp>(
            {prefix + "unix_timestamp", prefix + "to_unix_timestamp"});
        register_function<UnixTimestampParseWithFormatFunction, int64_t, Date>(
            {prefix + "unix_timestamp", prefix + "to_unix_timestamp"});
        register_function<FromUnixtimeFunction, Varchar, int64_t, Varchar>(
            {prefix + "from_unixtime"});
        register_function<MakeDateFunction, Date, int32_t, int32_t, int32_t>(
            {prefix + "make_date"});
        register_function<DateDiffFunction, int32_t, Date, Date>(
            {prefix + "datediff"});
        register_function<LastDayFunction, Date, Date>({prefix + "last_day"});
        register_function<AddMonthsFunction, Date, Date, int32_t>(
            {prefix + "add_months"});
        register_function<DateAddFunction, Date, Date, int8_t>({prefix + "date_add"});
        register_function<DateAddFunction, Date, Date, int16_t>({prefix + "date_add"});
        register_function<DateAddFunction, Date, Date, int32_t>({prefix + "date_add"});
        register_function<FormatDateTimeFunction, Varchar, Timestamp, Varchar>(
            {prefix + "date_format"});
        register_function<DateFromUnixDateFunction, Date, int32_t>(
            {prefix + "date_from_unix_date"});
        register_function<DateSubFunction, Date, Date, int8_t>({prefix + "date_sub"});
        register_function<DateSubFunction, Date, Date, int16_t>({prefix + "date_sub"});
        register_function<DateSubFunction, Date, Date, int32_t>({prefix + "date_sub"});
        register_function<DayFunction, int32_t, Date>(
            {prefix + "day", prefix + "dayofmonth"});
        register_function<DayOfYearFunction, int32_t, Date>(
            {prefix + "doy", prefix + "dayofyear"});
        register_function<DayOfWeekFunction, int32_t, Date>({prefix + "dayofweek"});
        register_function<WeekdayFunction, int32_t, Date>({prefix + "weekday"});
        register_function<QuarterFunction, int32_t, Date>({prefix + "quarter"});
        register_function<MonthFunction, int32_t, Date>({prefix + "month"});
        register_function<NextDayFunction, Date, Date, Varchar>({prefix + "next_day"});
        register_function<GetTimestampFunction, Timestamp, Varchar, Varchar>(
            {prefix + "get_timestamp"});
        register_function<HourFunction, int32_t, Timestamp>({prefix + "hour"});
        register_function<MinuteFunction, int32_t, Timestamp>({prefix + "minute"});
        register_function<SecondFunction, int32_t, Timestamp>({prefix + "second"});
        register_function<MakeYMIntervalFunction, IntervalYearMonth>(
            {prefix + "make_ym_interval"});
        register_function<MakeYMIntervalFunction, IntervalYearMonth, int32_t>(
            {prefix + "make_ym_interval"});
        register_function<MakeYMIntervalFunction, IntervalYearMonth, int32_t, int32_t>(
            {prefix + "make_ym_interval"});
        POLLUX_REGISTER_VECTOR_FUNCTION(udf_make_timestamp, prefix + "make_timestamp");
        register_function<TimestampToMicrosFunction, int64_t, Timestamp>(
            {prefix + "unix_micros"});
        registerUnaryIntegralWithTReturn<MicrosToTimestampFunction, Timestamp>(
            {prefix + "timestamp_micros"});
        register_function<TimestampToMillisFunction, int64_t, Timestamp>(
            {prefix + "unix_millis"});
        registerUnaryIntegralWithTReturn<MillisToTimestampFunction, Timestamp>(
            {prefix + "timestamp_millis"});
        register_function<DateTruncFunction, Timestamp, Varchar, Timestamp>(
            {prefix + "date_trunc"});
    }
} // namespace kumo::pollux::functions::sparksql
